// vim:ts=4:sw=4:expandtab
#ifndef __NEIKU_TSM_H__
#define __NEIKU_TSM_H__

#include <inttypes.h>
#include <string>
#include <map>

namespace neiku
{

// 标准输入输出
typedef std::map<std::string, std::string> data_t;
std::string data_get(const data_t& d, const std::string& k, bool* ok);

// 处理器抽象接口定义
class Processor {
public:
    // 处理逻辑，in是输出，out是输出，返回码0表示成功，负数表示不可重试，否则可重试
    virtual int process(const data_t& in, data_t& out) = 0;

    // 实现json之间转换，用于持久化（一种可恢复设计）
    virtual CJsonEncoder& serialize(CJsonEncoder& ar) = 0;
    virtual CJsonDecoder& serialize(CJsonDecoder& ar) = 0;
};

// PROCESSOR_BUILDER(特定处理器类型) 自动生成特定处理器类型的build成员方法代码
#define PROCESSOR_BUILDER(P) \
    static Processor* build(const std::string& body) \
    { \
        P *p = new(P); \
        if (body != "") { \
            json_decode(body, *p); \
        } \
        return p; \
    }

#define REGISTER_PROCESSOR_BUILDER(P, N, FN) \
    __attribute((constructor)) void FN() \
    { \
        ProcessorBuilers()[N] = P::build; \
    }

// 空处理器: 输入什么就输出什么，一般用于兜底。
class NoopProcess : public Processor {
public:
#define NoopProcess_serialize(AR) \
    AR& serialize(AR& ar) \
    { \
        return ar; \
    }
    NoopProcess_serialize(CJsonEncoder);
    NoopProcess_serialize(CJsonDecoder);
    PROCESSOR_BUILDER(NoopProcess);

    // 实现处理器
    int process(const data_t& in, data_t& out);
};

// 处理器生成工厂方法池
typedef Processor* (*ProcessorBuilderFn)(const std::string& body);
std::map<std::string, ProcessorBuilderFn>& ProcessorBuilers();
Processor* NewProcessor(const std::string& name, const std::string& body);

// 任务处理器
class TSMProcessor {
public:
    std::string name;     // 处理器名字
    Processor *processor; // 处理器实例
    data_t in;            // 处理器输入
    data_t out;           // 处理器输出

    TSMProcessor(): processor(NULL)
    {}

    template<typename AR>
    AR& serialize(AR& ar)
    {
        SERIALIZE(ar, name);
        if (processor == NULL) {
            processor = NewProcessor(name, "");
        }
        SERIALIZE_WITH_NAME(ar, "processor", *processor);
        SERIALIZE(ar, in);
        SERIALIZE(ar, out);
        return ar;
    }
};

// 任务状态机
class TSM {
public:
    data_t in; // 输入
    data_t out; // 输出
    size_t processor_cursor; // 当前处理器下标
    std::vector<TSMProcessor> processors; // 处理器链表

    TSM(): processor_cursor(0)
    {}

    template<typename AR>
    AR& serialize(AR& ar)
    {
        SERIALIZE(ar, in);
        SERIALIZE(ar, out);
        SERIALIZE(ar, processor_cursor);
        SERIALIZE(ar, processors);
        return ar;
    }

    // 从json恢复
    int recover(const std::string& body);

    // 执行任务
    int process();
};

};
#endif